package com.pz.cloud.framework.material.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Joiner;
import com.pz.cloud.framework.base.dao.CommonDao;
import com.pz.cloud.framework.base.expection.CustomRuntimeException;
import com.pz.cloud.framework.business.material.entity.Material;
import com.pz.cloud.framework.business.material.entity.MaterialApply;
import com.pz.cloud.framework.business.material.entity.MaterialApplyDetail;
import com.pz.cloud.framework.business.material.service.IMaterialApplyDetailService;
import com.pz.cloud.framework.business.material.service.IMaterialApplyService;
import com.pz.cloud.framework.business.material.service.IMaterialService;
import com.pz.cloud.framework.business.workflow.annotation.Workflow;
import com.pz.cloud.framework.material.callback.MaterialApplyCallback;
import com.pz.cloud.framework.material.mapper.MaterialApplyMapper;
import com.pz.cloud.framework.model.AbstractSqlBuilder;
import com.pz.cloud.framework.model.SqlBuilder;
import org.apache.commons.lang.StringUtils;
import org.jeecg.modules.system.entity.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Transactional
public class MaterialApplyServiceImpl extends ServiceImpl<MaterialApplyMapper, MaterialApply> implements IMaterialApplyService {

    @Autowired
    private IMaterialService materialService;
    @Autowired
    private IMaterialApplyDetailService materialApplyDetailService;

    @Autowired
    private CommonDao commonDao;

    @Override
    @Workflow(callback = MaterialApplyCallback.class)
    public boolean add(MaterialApply materialApply) {
        boolean flag = false;
        if(StringUtils.isEmpty(materialApply.getId())) {
//            String materialId = materialApply.getMaterialId();
//            Material material = materialService.getById(materialId);
//            if (material == null) {
//                throw new CustomRuntimeException("该场地或物资不存在");
//            }
//            if (material.getStatus() != 1) {
//                throw new CustomRuntimeException("该场地或物资暂不可用");
//            }
//            if (materialApply.getCount() != null && materialApply.getCount() > material.getCount()) {
//                throw new CustomRuntimeException("申请数量超过可用数量，最多：" + material.getCount());
//            }

            /*AbstractSqlBuilder sqlBuilder = SqlBuilder.init("select u.realname from ")
                    .appendTable(MaterialApply.class).append(" ma ")
                    .append("left join ").appendTable(SysUser.class).append(" u on ma.applier_id = u.id and u.del_flag = 0")
                    .append(" where ma.del_flag = 0 and ((ma.start_time < :startTime and end_time > :startTime)")
                    .append(" or (ma.start_time > :startTime and start_time < :endTime)")
                    .append(" or (ma.end_time > :endTime and start_time < :endTime))")
                    .setParms("startTime", materialApply.getStartTime())
                    .setParms("endTime", materialApply.getEndTime())
                    .returnType(MaterialApply.class);
            List<MaterialApply> list = commonDao.findList(sqlBuilder);
            if (!CollectionUtils.isEmpty(list)) {
                List<String> names = list.stream().map(MaterialApply::getRealname).collect(Collectors.toList());
                throw new CustomRuntimeException("该时间段与[" + Joiner.on("，").join(names) + "]的申请存在冲突");
            }*/
            flag = super.save(materialApply);

            List<MaterialApplyDetail> details = materialApply.getDetails();
            if(details!=null){
                for (MaterialApplyDetail detail : details) {
                    detail.setApplyId(materialApply.getId());
                }
                materialApplyDetailService.saveBatch(details);
            }
        } else {
            MaterialApply byId = super.getById(materialApply.getId());
            if (byId != null) {
                materialApplyDetailService.deleteByApplyId(materialApply.getId());
                List<MaterialApplyDetail> details = materialApply.getDetails();
                for (MaterialApplyDetail detail : details) {
                    detail.setApplyId(materialApply.getId());
                }
                materialApplyDetailService.saveBatch(details);

                flag = super.updateById(materialApply);
            }
        }
        materialApply.getWorkflowModel().setHandlerId(materialApply.getInstructorId());

        return flag;
    }

    @Override
    public IPage<MaterialApply> findPage(MaterialApply material, Map<String, String[]> parameterMap) {
//        AbstractSqlBuilder sqlBuilder = SqlBuilder.init("select u.realname,ma.*,m.type material_type,m.name material_name,m.code material_code from ")
//                .appendTable(MaterialApply.class).append(" ma ")
//                .append("inner join ").appendTable(Material.class).append(" m on ma.material_id = m.id ")
//                .append("left join ").appendTable(SysUser.class).append(" u on ma.applier_id = u.id and u.del_flag = 0 ")
//                .orderBy("ma.id desc")
//                .returnType(MaterialApply.class)
//                .page(material)
//                .joinCondition(material, "ma", parameterMap);
        AbstractSqlBuilder sqlBuilder = SqlBuilder.init("select ma.*,ad.detailNames from ")
                .appendTable(MaterialApply.class).append(" ma ")
                .append("left join (select group_concat(material_name) as detailNames, apply_id from ").appendTable(MaterialApplyDetail.class)
                .append(" group by apply_id) ad on ma.id = ad.apply_id ")
                .orderBy("ma.create_time desc")
                .returnType(MaterialApply.class)
                .page(material)
                .filterDataScope("ma");
        return commonDao.findPage(sqlBuilder);
    }

    @Override
    public boolean removeById(Serializable id) {
        materialApplyDetailService.deleteByApplyId((String) id);
        return  super.removeById(id);
    }

    @Override
    public boolean removeByIds(Collection<? extends Serializable> idList) {
        for (Serializable id : idList) {
            materialApplyDetailService.deleteByApplyId((String) id);
        }
        return super.removeByIds(idList);
    }
}
